home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DGPL.ZIP / 3DGPL / CODE / TRANS / TRANS-FX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-22  |  10.9 KB  |  286 lines

  1. /** 3DGPL *************************************************\
  2.  *  ()                                                    *
  3.  *  3-D transformations of coordinates using fixed point. *
  4.  *                                                        *
  5.  *  Defines:                                              *
  6.  *   T_init_math             Creating sin/cos tables;     *
  7.  *                                                        *
  8.  *   T_translation           Shifting of coordinates;     *
  9.  *   T_scaling               Scaling coordinates;         *
  10.  *                                                        *
  11.  *   T_set_world_rotation    Viewer's rotation;           *
  12.  *   T_world_rotation        Transforming coordinates;    *
  13.  *   T_set_self_rotation     Object rotation;             *
  14.  *   T_self_rotation         Transforming coordinates;    *
  15.  *                                                        *
  16.  *   T_perspective           Transform to perspective.    *
  17.  *                                                        *
  18.  *  Internals:                                            *
  19.  *   TI_float2fixed          Converting float to fixed.   *
  20.  *                                                        *
  21.  *  (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca).    *
  22.  *  Copyright (c) 1995 Sergei Savchenko.                  *
  23.  *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
  24.  *  WITHOUT AUTHORISATION                                 *
  25. \**********************************************************/
  26.  
  27. #include <math.h>                           /* sin & cos */
  28. #include "../hardware/hardware.h"           /* 32bit int name */
  29. #include "../trans/trans.h"                 /* 3D mathematics */
  30.  
  31. typedef signed_32_bit fixed;                /* better be 32bit machine */
  32.  
  33. #define T_RADS                  40.7436642  /* pseudo-grads into rads */
  34. #define T_P                             14  /* fixed math precision */
  35.  
  36. fixed T_wx1,T_wx2,T_wx3,T_wy1,T_wy2,T_wy3,T_wz1,T_wz2,T_wz3;
  37. fixed T_sx1,T_sx2,T_sx3,T_sy1,T_sy2,T_sy3,T_sz1,T_sz2,T_sz3;
  38. fixed T_sin[256],T_cos[256];                /* precalculated */
  39.  
  40. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 
  41.  *  INTERNAL: Converting [-1,1] float into fixed.        *
  42.  *  ---------                                            *
  43. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  44.  
  45. fixed TI_float2fixed(float a)
  46.  fixed res=0;
  47.  int i,dv,sign;
  48.  
  49.  if((sign=a<0.0)==1) a=-a;
  50.  
  51.  for(i=1,dv=2;i<=T_P;i++,dv*=2)
  52.   if(a>=1.0/dv) { a-=1.0/dv; res|=(0x1<<(T_P-i)); };
  53.  
  54.  if(sign==1) res=-res;
  55.  
  56.  return(res);
  57. }
  58.  
  59. /**********************************************************\
  60.  *  Initializing tables.                                  *
  61. \**********************************************************/
  62.  
  63. void T_init_math(void)
  64. {
  65.  int i;
  66.  
  67.  for(i=0;i<256;i++)
  68.  {
  69.   T_sin[i]=TI_float2fixed(sin(i/T_RADS));
  70.   T_cos[i]=TI_float2fixed(cos(i/T_RADS));
  71.  }
  72.  
  73. /**********************************************************\
  74.  *  Translation of coordinates.                           *
  75. \**********************************************************/
  76.  
  77. void T_translation(register int *from,register int *to,int length,
  78.            int addx,int addy,int addz
  79.           )
  80. {
  81.  register int i;
  82.  
  83.  for(i=0;i<length;i++)
  84.  {
  85.   (*to++)=(*from++)+addx;
  86.   (*to++)=(*from++)+addy;
  87.   (*to++)=(*from++)+addz;                   /* translation */
  88.  }
  89. }
  90.  
  91. /**********************************************************\
  92.  *  Scaling coordinates. (takes in float parameters).     *
  93. \**********************************************************/
  94.  
  95. void T_scaling(register int *from,register int *to,int length,
  96.            int mulx,int muly,int mulz
  97.           )
  98. {
  99.  register int i;
  100.  
  101.  for(i=0;i<length;i++)
  102.  {
  103.   (*to++)=(int)(*from++)*mulx;
  104.   (*to++)=(int)(*from++)*muly;
  105.   (*to++)=(int)(*from++)*mulz;
  106.  }                                          /* scaling */
  107. }
  108.  
  109. /**********************************************************\
  110.  *  Constructing rotation matrix. (gam-bet-alp), rotation *
  111.  *  then pitch then roll sequence. gam-rotation, bet-pitch*
  112.  *                                 alp-roll.              *
  113.  *                                                        *
  114.  *          Y^    Z           x'=z*sin(gam)+x*cos(gam)    *
  115.  *           |   /            y'=y                        *
  116.  *           |  / alp         z'=z*cos(gam)-x*sin(gam)    *
  117.  *          /|<---+                                       *
  118.  *         | |/   |           x"=x'                       *
  119.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  120.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  121.  *         V/|   /| gam                                   *
  122.  *         /----+             x"'=y"*sin(alp)+x"*cos(alp) *
  123.  *        /  |                y"'=y"*cos(alp)-x"*sin(alp) *
  124.  *       /   |                z"'=z"                      *
  125.  *           |                                            *
  126. \**********************************************************/
  127.  
  128. void T_set_world_rotation(int alp,int bet,int gam)
  129. {
  130.  fixed cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  131.  
  132.  cosalp=T_cos[alp];
  133.  sinalp=T_sin[alp];
  134.  cosbet=T_cos[bet];
  135.  sinbet=T_sin[bet];
  136.  cosgam=T_cos[gam];
  137.  singam=T_sin[gam];                         /* initializing */
  138.  
  139.  T_wx1=((singam*((sinbet*sinalp)>>T_P))>>T_P) + ((cosgam*cosalp)>>T_P);
  140.  T_wy1=((cosbet*sinalp)>>T_P);
  141.  T_wz1=((singam*cosalp)>>T_P) - ((cosgam*((sinbet*sinalp)>>T_P))>>T_P);
  142.  
  143.  T_wx2=((singam*((sinbet*cosalp)>>T_P))>>T_P) - ((cosgam*sinalp)>>T_P);
  144.  T_wy2=((cosbet*cosalp)>>T_P);
  145.  T_wz2=-((cosgam*((sinbet*cosalp)>>T_P))>>T_P) - ((singam*sinalp)>>T_P);
  146.  
  147.  T_wx3=-((singam*cosbet)>>T_P);
  148.  T_wy3=sinbet;
  149.  T_wz3=((cosgam*cosbet)>>T_P);              /* calculating the matrix */
  150. }
  151.  
  152. /**********************************************************\
  153.  *  Rotating coordinates.                                 *
  154.  *                                        |wx1 wx2 wx3|   *
  155.  *  T'=T[W]  where:  [x' y' z'] = [x y z]*|wy1 wy2 wy3|   *
  156.  *                                        |wz1 wz2 wz3|   *
  157. \**********************************************************/
  158.  
  159. void T_world_rotation(int *from,register int *to,int length)
  160. {
  161.  register int i;
  162.  register int xt,yt,zt;
  163.  
  164.  for(i=0;i<length;i++)
  165.  {
  166.   xt=*from++;
  167.   yt=*from++;
  168.   zt=*from++;
  169.  
  170.   *to++=((T_wx1*xt)>>T_P) + ((T_wy1*yt)>>T_P) + ((T_wz1*zt)>>T_P);
  171.   *to++=((T_wx2*xt)>>T_P) + ((T_wy2*yt)>>T_P) + ((T_wz2*zt)>>T_P);
  172.   *to++=((T_wx3*xt)>>T_P) + ((T_wy3*yt)>>T_P) + ((T_wz3*zt)>>T_P); 
  173.  }
  174. }
  175.  
  176. /**********************************************************\
  177.  *  Constructing rotation matrix. (alp-bet-gam), roll     *
  178.  *  then pitch then rotation sequence. gam-rotation,      *
  179.  *                                     bet-pitch, alp-roll*
  180.  *                                                        *
  181.  *          Y^    Z           x'=y*sin(alp)+x*cos(alp)    *
  182.  *           |   /            y'=y*cos(alp)-x*sin(alp)    *
  183.  *           |  / alp         z'=z                        *
  184.  *          /|<---+                                       *
  185.  *         | |/   |           x"=x'                       *
  186.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  187.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  188.  *         V/|   /| gam                                   *
  189.  *         /----+             x"'=z"*sin(gam)+x"*cos(gam) *
  190.  *        /  |                y"'=y"                      *
  191.  *       /   |                z"'=z"*cos(gam)-x"*sin(gam) *
  192.  *           |                                            *
  193. \**********************************************************/
  194.  
  195. void T_set_self_rotation(int alp,int bet,int gam)
  196.  fixed cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  197.  
  198.  cosalp=T_cos[alp];
  199.  sinalp=T_sin[alp];
  200.  cosbet=T_cos[bet];
  201.  sinbet=T_sin[bet];
  202.  cosgam=T_cos[gam];
  203.  singam=T_sin[gam];                         /* initializing */
  204.  
  205.  T_sx1=((cosalp*cosgam)>>T_P)-((sinalp*((sinbet*singam)>>T_P))>>T_P);
  206.  T_sy1=((sinalp*cosgam)>>T_P)+((cosalp*((sinbet*singam)>>T_P))>>T_P);
  207.  T_sz1=((cosbet*singam)>>T_P);
  208.  
  209.  T_sx2=-((sinalp*cosbet)>>T_P);
  210.  T_sy2=((cosalp*cosbet)>>T_P);
  211.  T_sz2=-sinbet;
  212.  
  213.  T_sx3=-((cosalp*singam)>>T_P)-((sinalp*((sinbet*cosgam)>>T_P))>>T_P);
  214.  T_sy3=((cosalp*((sinbet*cosgam)>>T_P))>>T_P)-((sinalp*singam)>>T_P);
  215.  T_sz3=((cosbet*cosgam)>>T_P);              /* calculating the matrix */
  216. }
  217.  
  218. /**********************************************************\
  219.  *  Rotating coordinates.                                 *
  220.  *                                        |sx1 sx2 sx3|   *
  221.  *  T'=T[S]  where:  [x' y' z'] = [x y z]*|sy1 sy2 sy3|   *
  222.  *                                        |sz1 sz2 sz3|   *
  223. \**********************************************************/
  224.  
  225. void T_self_rotation(int *from,register int *to,int length)
  226. {
  227.  register int i;
  228.  register int xt,yt,zt;
  229.  
  230.  for(i=0;i<length;i++)
  231.  {
  232.   xt=*from++;
  233.   yt=*from++;
  234.   zt=*from++;
  235.  
  236.   *to++=((T_sx1*xt)>>T_P) + ((T_sy1*yt)>>T_P) + ((T_sz1*zt)>>T_P);
  237.   *to++=((T_sx2*xt)>>T_P) + ((T_sy2*yt)>>T_P) + ((T_sz2*zt)>>T_P);
  238.   *to++=((T_sx3*xt)>>T_P) + ((T_sy3*yt)>>T_P) + ((T_sz3*zt)>>T_P); 
  239.  }
  240. }
  241.  
  242. /**********************************************************\
  243.  *  Transforming to perspective, coordinates passed ase   *
  244.  *                        supposed to be both volume, and *
  245.  *                *       Z-clipped, otherwise division   *
  246.  *               /|X      by 0 or overflow can occur.     *
  247.  *              / |                                       *
  248.  *             /  |                                       *
  249.  *            *   |                                       *
  250.  *           /|X' |       X'      X                       *
  251.  *          / |   |    ------- = ---                      *
  252.  *         /  |   |     focus     Z                       *
  253.  *        *---+---+                                       *
  254.  *        0   ^   Z    X'= X*focus/Z                      *
  255.  *            |                                           *
  256.  *          focus                                         *
  257.  *                                                        *
  258.  *  ADDITIONAL FUNCTIONS: 1) changing formats:            *
  259.  *  ---------------------                                 *
  260.  *    source:       x, y ,z,a1,...,aN where N==dimension-3*
  261.  *    destanation:  x',y',  a1,...,aN                     *   
  262.  *                                                        *
  263.  *  2) performs translation to the screen centre.         *
  264. \**********************************************************/
  265.  
  266. void T_perspective(register int *from,register int *to,
  267.            int dimension,int length
  268.           )
  269. {
  270.  register int i;
  271.  
  272.  dimension-=3;                              /* other then X,Y */
  273.  
  274.  for(i=0;i<length;i++,from+=dimension,to+=dimension) 
  275.  {                                          /* Z is not being changed */
  276.   to[0]=((((long)from[0])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_X_CENTRE;
  277.   to[1]=((((long)from[1])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_Y_CENTRE;
  278.   HW_copy_int(from+=3,to+=2,dimension);
  279.  }
  280. }
  281.  
  282. /**********************************************************/
  283.